package com.letoken.platform.app.job;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.letoken.platform.app.consumer.FundConsumer;
import com.letoken.platform.app.consumer.FundReleaseConsumer;
import com.letoken.platform.app.service.AppFundDetailService;
import com.letoken.platform.app.service.AppUserLampService;
import com.letoken.platform.app.service.AppFundInfoService;
import com.letoken.platform.app.service.AppUserWalletService;
import com.letoken.platform.pub.enums.LetokenTokenTypeEnum;
import com.letoken.platform.pub.enums.TokenTransactionStatusEnum;
import com.letoken.platform.pub.enums.TokenTransactionTypeEnum;
import com.letoken.platform.pub.res.ApiResponse;
import com.letoken.platform.repo.admin.dao.AdminFundConfigMapper;
import com.letoken.platform.repo.admin.po.AdminFundConfig;
import com.letoken.platform.repo.app.dao.*;
import com.letoken.platform.repo.app.po.*;
import com.letoken.platform.repo.helper.CalculateConsumerValue;
import com.letoken.platform.repo.mall.dao.AppMallAmbassadorMapper;
import com.letoken.platform.repo.mall.po.AppMallAmbassador;
import com.letoken.platform.repo.wallet.constant.MallRabbitConstant;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.web3j.abi.datatypes.Int;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Slf4j
public class FundIncomeJob {

    @Resource
    private AppFundInfoMapper appFundInfoMapper;


    @Autowired
    private AppFundDetailService appFundDetailService;

    @Resource
    AppUserAssetsHistoryMapper appUserAssetsHistoryMapper;

    @Resource
    AppUserWalletMapper appUserWalletMapper;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Resource
    AdminFundConfigMapper adminFundConfigMapper;


    @Resource
    AppFundRankingMapper appFundRankingMapper;

    @Resource
    AdminFundRankConfigMapper adminFundRankConfigMapper;

    @Resource
    AppFundRankInfoMapper appFundRankInfoMapper;

    @Resource
    AppMallAmbassadorMapper appMallAmbassadorMapper;
    @Autowired
    CalculateConsumerValue calculateConsumerValue;
    @Autowired
    AppFundInfoService appFundInfoService;

    @Autowired
    AppUserLampService appUserLampService;

    @Autowired
    AppUserWalletService appUserWalletService;

    @Resource
    private AdminFundDistributeConfigMapper adminFundDistributeConfigMapper;

    //@XxlJob("income")
    public  void income() {
        calculateConsumerValue.calculateConsumerMark(new CalculateConsumerValue.ConsumerValuePo());


       List<Integer> fundUserIdList= appFundInfoMapper.getFundUserId();
        BigDecimal bigDecimal = BigDecimal.ZERO;
        List<AdminFundConfig> configList = adminFundConfigMapper.selectList(new QueryWrapper<>());
        for (Integer userId:fundUserIdList) {
           List<AppFundInfo> infoList = appFundInfoMapper.getFundByUserId(userId);
            //自己可拿奖励总额
            BigDecimal sumFund = BigDecimal.ZERO;
            //给上级带来奖励的总额
            BigDecimal  award = BigDecimal.ZERO;
            for (AppFundInfo appFundInfo:infoList) {
                BigDecimal rate = configList.stream().filter(s->s.getId().equals(appFundInfo.getFundId())).collect(Collectors.toList()).get(0).getRate();
                appFundInfo.setAmount(appFundInfo.getFund().multiply(rate));
                sumFund = sumFund.add(appFundInfo.getAmount());
                if(appFundInfo.getState().equals(1)){
                    award = award.add(appFundInfo.getAmount());
                }
            }
            AppFundDetail appFundDetail = new AppFundDetail();
            appFundDetail.setAmount(sumFund);
            appFundDetail.setCreateTime(LocalDateTime.now());
            appFundDetail.setType(1);
            appFundDetail.setUserId(userId);
            appFundDetailService.save(appFundDetail);
            //  给所有等级奖励总额
            bigDecimal = bigDecimal.add(award);

            Integer walletId = appUserWalletMapper.checkoutTokenIdAndUserId(LetokenTokenTypeEnum.LET.getId(),userId);
            if (/*ObjectUtils.isEmpty(balanceId) ||*/ ObjectUtils.isEmpty(walletId)){
                continue;
            }
            AppUserWallet w = appUserWalletMapper.selectForUpdate(walletId);
            AppUserWallet updateW = new AppUserWallet();
            updateW.setId(w.getId());
            updateW.setAvailableBalance(w.getAvailableBalance().add(sumFund));
            appUserWalletMapper.updateById(updateW);

            AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
            assetHistory.setUserId(userId);
            assetHistory.setType(TokenTransactionTypeEnum.FUND_REWARD.getValue());
            assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
            assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
            assetHistory.setAmount(sumFund);
            assetHistory.setBalance(updateW.getAvailableBalance());
            assetHistory.setCreateTime(LocalDateTime.now());
            assetHistory.setUpdateTime(assetHistory.getCreateTime());
            appUserAssetsHistoryMapper.insert(assetHistory);

            queueBonus(userId,award);
        }
        queueWeighting(bigDecimal);
    }

    public void queueBonus(Integer userId,BigDecimal amount){

        FundConsumer.BonusDto dto = new FundConsumer.BonusDto();
        dto.setAmount(amount);
        dto.setUserId(userId);
        rabbitTemplate.convertAndSend(FundConsumer.exchange, FundConsumer.queueBonus,  JSONObject.toJSON(dto).toString());
    }

    public void queueWeighting(BigDecimal amount){
        rabbitTemplate.convertAndSend(FundConsumer.exchange, FundConsumer.queueWeighting, amount);
    }


    @Resource
    private AppFundLevelInfoMapper appFundLevelInfoMapper;
    @Resource
    private AppUserTeamMapper appUserTeamMapper;



    @Resource
    private AdminFundLevelConfigMapper adminFundLevelConfigMapper;

    @XxlJob("getUserData")
    public ApiResponse getUserData() {
        List<AppMallAmbassador> list = appMallAmbassadorMapper.selectList(new QueryWrapper<>());
        for (AppMallAmbassador appMallAmbassador: list) {
            AppFundLevelInfo appFundLevelInfo = new AppFundLevelInfo();
            appFundLevelInfo.setUserId(appMallAmbassador.getUserId());
            appFundLevelInfo.setLevel(appMallAmbassador.getLevel()>0?appMallAmbassador.getLevel()+5:appMallAmbassador.getLevel());
            appFundLevelInfo.setCreateTime(appMallAmbassador.getCreateTime());
            appFundLevelInfo.insertOrUpdate();

        }
        return ApiResponse.create();
    }

    @XxlJob("lamp")
    public ApiResponse lamp() {
        appUserLampService.lamd();
        return ApiResponse.create();
    }
    @XxlJob("v5")
    public ApiResponse v5() {
        appFundInfoService.v5();;
        return ApiResponse.create();
    }

    @XxlJob("updatev5")
    public ApiResponse updatev5() {
        List<AppFundLevelInfo> appFundLevelInfos = appFundInfoMapper.updateLevelInfoList();
        for (AppFundLevelInfo appFundLevelInfo:appFundLevelInfos ) {
            Integer count = appFundInfoMapper.getLevelInfoListByInviterId(appFundLevelInfo.getUserId());
            if(count>0){
                for (int i = 0; i < count; i++) {
                    Integer walletId = appUserWalletMapper.checkoutTokenIdAndUserId(LetokenTokenTypeEnum.LET.getId(),appFundLevelInfo.getUserId());
                    if (org.apache.commons.lang3.ObjectUtils.isEmpty(walletId)){
                        continue;
                    }
                    AppUserWallet w = appUserWalletMapper.selectForUpdate(walletId);
                    AppUserWallet updateW = new AppUserWallet();
                    updateW.setId(w.getId());
                    updateW.setAvailableBalance(w.getAvailableBalance().add(new BigDecimal("15")));
                    appUserWalletMapper.updateById(updateW);

                    AppUserAssetsHistory assetHistory = new AppUserAssetsHistory();
                    assetHistory.setUserId(appFundLevelInfo.getUserId());
                    assetHistory.setType(TokenTransactionTypeEnum.V5.getValue());
                    assetHistory.setStatus(TokenTransactionStatusEnum.COMPLETED.getValue());
                    assetHistory.setTokenId(LetokenTokenTypeEnum.LET.getId());
                    assetHistory.setAmount(new BigDecimal("15"));
                    assetHistory.setBalance(updateW.getAvailableBalance());
                    assetHistory.setCreateTime(LocalDateTime.now());
                    assetHistory.setUpdateTime(assetHistory.getCreateTime());
                    appUserAssetsHistoryMapper.insert(assetHistory);
                }
            }
        }
        return ApiResponse.create();
    }



    @XxlJob("updateUserData")
    public ApiResponse updateUserData() {
        List<Integer> idList = appFundInfoMapper.getFundUser();
        List<AdminFundLevelConfig> levelConfigs = adminFundLevelConfigMapper.getLevelList();
        for (Integer id:idList) {
           AppUserTeam appUserTeam = appUserTeamMapper.selectById(id);
           if(appUserTeam != null && !appUserTeam.getInviterId().equals(0)){
               AppFundLevelInfo appFundLevelInfo =  appFundLevelInfoMapper.selectById(appUserTeam.getInviterId());

               if(appFundLevelInfo==null || appFundLevelInfo.getLevel()<6){
                   Integer count = appFundLevelInfoMapper.getFundByInviterIdCOunt(appUserTeam.getInviterId());
                   for (AdminFundLevelConfig adminFundLevelConfig:levelConfigs) {
                       if (count >= adminFundLevelConfig.getCondition()){
                           AppFundLevelInfo info = new AppFundLevelInfo();
                           info.setLevel(adminFundLevelConfig.getLevel());
                           info.setUserId(appUserTeam.getInviterId());
                           info.setUpdateTime(LocalDateTime.now());
                           info.setCreateTime(LocalDateTime.now());
                           info.insertOrUpdate();
                           break;
                       }
                   }
               }
           }
        }
        return ApiResponse.create();
    }

    @Resource
    AppFundV2InfoMapper appFundV2InfoMapper;

    @XxlJob("dayBouns")
    public void dayBouns() {
        LocalDateTime now = LocalDateTime.now();
        String endTime = now.getYear()+"-"+now.getMonthValue()+"-"+now.getDayOfMonth()+" 18:00:00";
        now = now.plusDays(-1);
        String startTime = now.getYear()+"-"+now.getMonthValue()+"-"+now.getDayOfMonth()+" 18:00:00";

        List<AppFundRanking> list = appFundRankingMapper.getAppFundRankingDesc1(startTime,endTime);
        List<AdminFundRankConfig> list1 = adminFundRankConfigMapper.selectList(new QueryWrapper());
        AppFundRankInfo appFundRanking = appFundRankInfoMapper.getRankInfoForupdate();
        if(appFundRanking.getDayAmount().compareTo(BigDecimal.ZERO)<=0){
            appFundRanking.updateById();
            return;
        }
        for (int i = 0; i < list.size(); i++) {
            AppFundRanking appFundRanking1 = list.get(i);
            int finalI = i;
            AdminFundRankConfig adminFundRankConfig =  list1.stream().filter(l->l.getRanking().equals(finalI +1)).collect(Collectors.toList()).get(0);
            BigDecimal  money = appFundRanking.getDayAmount().multiply(adminFundRankConfig.getRate());

            AppFundV2Info  appFundV2Info = appFundV2InfoMapper.selectBYUserId(appFundRanking1.getUserId());
            if(org.springframework.util.ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(BigDecimal.ZERO) == 0){
                AppRankingDetail appRankingDetail = new AppRankingDetail();
                appRankingDetail.setRanking(i+1);
                appRankingDetail.setAmount(BigDecimal.ZERO);
                appRankingDetail.setType(1);
                appRankingDetail.setUserId(appFundRanking1.getUserId());
                appRankingDetail.setCreateTime(LocalDateTime.now());
                appRankingDetail.setPerformance(appFundRanking1.getAmount());
                appRankingDetail.setSumAmount(appFundRanking.getDayAmount());
                appRankingDetail.insert();
            }else {
                if(money.compareTo(appFundV2Info.getRetained()) > 0){
                    money = appFundV2Info.getRetained();
                }
                AppFundV2Info appFundV2Info1 = appFundInfoService.updateInfo(appFundRanking1.getUserId(),money,BigDecimal.ZERO);
                AppFundV2Detail appFundV2Detail = new AppFundV2Detail();
                appFundV2Detail.setAmount(money);
                appFundV2Detail.setUserId(appFundV2Info.getUserId());
                appFundV2Detail.setCreateTime(LocalDateTime.now());
                appFundV2Detail.setAfterAmount(appFundV2Info1.getRetained());
                appFundV2Detail.setType(11);
                appFundV2Detail.insert();
                Integer walletId = appUserWalletMapper.checkoutTokenIdAndUserId(LetokenTokenTypeEnum.LET.getId(),appFundRanking1.getUserId());
                if (ObjectUtils.isEmpty(walletId)){
                    continue;
                }
                appUserWalletService.updateWallet(LetokenTokenTypeEnum.LET.getId(),appFundRanking1.getUserId(),money,TokenTransactionTypeEnum.DAY_BOUS.getValue(),"");
                AppRankingDetail appRankingDetail = new AppRankingDetail();
                appRankingDetail.setRanking(i+1);
                appRankingDetail.setAmount(money);
                appRankingDetail.setType(1);
                appRankingDetail.setUserId(appFundRanking1.getUserId());
                appRankingDetail.setCreateTime(LocalDateTime.now());
                appRankingDetail.setPerformance(appFundRanking1.getAmount());
                appRankingDetail.setSumAmount(appFundRanking.getDayAmount());
                appRankingDetail.insert();

                fundRelease(appFundV2Info.getUserId(),money);
            }
        }

        AppFundRankInfo appFundRanking1 = new AppFundRankInfo();
        appFundRanking1.setDayAmount(BigDecimal.ZERO);
        appFundRanking1.setUpdateTime(LocalDateTime.now());
        appFundRanking1.setId(1);
        appFundRankInfoMapper.updateById(appFundRanking1);
    }

    @XxlJob("weekBouns")
    @Transactional
    public void weekBouns() {
        LocalDateTime now = LocalDateTime.now();
        String endTime = now.getYear()+"-"+now.getMonthValue()+"-"+now.getDayOfMonth()+" 18:00:00";
        now = now.plusDays(-7);
        String startTime = now.getYear()+"-"+now.getMonthValue()+"-"+now.getDayOfMonth()+" 18:00:00";

        List<AppFundRanking> list = appFundRankingMapper.getAppFundRankingDesc7(startTime,endTime);
        List<AdminFundRankConfig> list1 = adminFundRankConfigMapper.selectList(new QueryWrapper());
        AppFundRankInfo appFundRanking = appFundRankInfoMapper.getRankInfoForupdate();
        if(appFundRanking.getWeekAmout().compareTo(BigDecimal.ZERO)<=0){
            appFundRanking.updateById();
            return;
        }

        for (int i = 0; i < list.size(); i++) {
            AppFundRanking appFundRanking1 = list.get(i);
            /*AppFundRanking appFundRanking2 = new AppFundRanking();
            appFundRanking2.setType(2);
            if(i>=list1.size()){
                appFundRanking2.update(new QueryWrapper<AppFundRanking>().eq("user_id",appFundRanking1.getUserId()));
                continue;
            }*/
            /*if(appMallAmbassadorMapper.getCountByUserAndLevel(appFundRanking1.getUserId())<=0){
                appFundRanking2.update(new QueryWrapper<AppFundRanking>().eq("user_id",appFundRanking1.getUserId()));
                continue;
            }*/
            int finalI = i;
            AdminFundRankConfig adminFundRankConfig =  list1.stream().filter(l->l.getRanking().equals(finalI +1)).collect(Collectors.toList()).get(0);
            BigDecimal  money = appFundRanking.getWeekAmout().multiply(adminFundRankConfig.getRate());


            AppFundV2Info  appFundV2Info = appFundV2InfoMapper.selectBYUserId(appFundRanking1.getUserId());
            if(org.springframework.util.ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(BigDecimal.ZERO) == 0){
                AppRankingDetail appRankingDetail = new AppRankingDetail();
                appRankingDetail.setRanking(i+1);
                appRankingDetail.setAmount(BigDecimal.ZERO);
                appRankingDetail.setType(2);
                appRankingDetail.setUserId(appFundRanking1.getUserId());
                appRankingDetail.setCreateTime(LocalDateTime.now());
                appRankingDetail.setPerformance(appFundRanking1.getAmount());
                appRankingDetail.setSumAmount(appFundRanking.getWeekAmout());
                appRankingDetail.insert();
            }else {
                if(money.compareTo(appFundV2Info.getRetained()) > 0){
                    money = appFundV2Info.getRetained();
                }

                AppFundV2Info appFundV2Info1 = appFundInfoService.updateInfo(appFundRanking1.getUserId(),money,BigDecimal.ZERO);

                AppFundV2Detail appFundV2Detail = new AppFundV2Detail();
                appFundV2Detail.setAmount(money);
                appFundV2Detail.setUserId(appFundV2Info.getUserId());
                appFundV2Detail.setCreateTime(LocalDateTime.now());
                appFundV2Detail.setAfterAmount(appFundV2Info1.getRetained());
                appFundV2Detail.setType(12);
                appFundV2Detail.insert();


                AppRankingDetail appRankingDetail = new AppRankingDetail();
                appRankingDetail.setRanking(i+1);
                appRankingDetail.setAmount(money);
                appRankingDetail.setType(2);
                appRankingDetail.setUserId(appFundRanking1.getUserId());
                appRankingDetail.setCreateTime(LocalDateTime.now());
                appRankingDetail.setPerformance(appFundRanking1.getAmount());
                appRankingDetail.setSumAmount(appFundRanking.getWeekAmout());
                appRankingDetail.insert();

                Integer walletId = appUserWalletMapper.checkoutTokenIdAndUserId(LetokenTokenTypeEnum.LET.getId(),appFundRanking1.getUserId());
                if (ObjectUtils.isEmpty(walletId)){
                    continue;
                }

                appUserWalletService.updateWallet(LetokenTokenTypeEnum.LET.getId(),appFundRanking1.getUserId(),money,TokenTransactionTypeEnum.WEEK_BOUS.getValue(),"");

                fundRelease(appFundV2Info.getUserId(),money);
            }
        }
        appFundRankInfoMapper.updateType();
        AppFundRankInfo appFundRanking1 = new AppFundRankInfo();
        appFundRanking1.setWeekAmout(BigDecimal.ZERO);
        appFundRanking1.setUpdateTime(LocalDateTime.now());
        appFundRanking1.setId(1);
        appFundRankInfoMapper.updateById(appFundRanking1);
    }

    @XxlJob("addAmount")
    public void addAmount() {
        LocalDateTime now = LocalDateTime.now();
        String endTime = now.getYear()+"-"+now.getMonthValue()+"-"+now.getDayOfMonth()+" 18:00:00";
        now = now.plusDays(-1);
        String startTime = now.getYear()+"-"+now.getMonthValue()+"-"+now.getDayOfMonth()+" 18:00:00";

        BigDecimal amount = adminFundConfigMapper.getFundBankList(startTime,endTime);
        if (amount.compareTo(BigDecimal.ZERO) <= 0)return;
        BigDecimal day = BigDecimal.ZERO;
        BigDecimal week = BigDecimal.ZERO;;
        AdminFundDistributeConfig adminFundDistributeConfig = adminFundDistributeConfigMapper.selectById(1);

        day = day.add(amount.multiply(adminFundDistributeConfig.getDayRate()));
        week = week.add(amount.multiply(adminFundDistributeConfig.getWeekRate()));

        AppFundRankInfo appFundRankInfo = appFundRankInfoMapper.getRankInfoForupdate();

        AppFundRankInfo appFundRanking1 = new AppFundRankInfo();
        appFundRanking1.setWeekAmout(week.add(appFundRankInfo.getWeekAmout()));
        appFundRanking1.setDayAmount(day);
        appFundRanking1.setUpdateTime(LocalDateTime.now());
        appFundRanking1.setId(1);
        appFundRankInfoMapper.updateById(appFundRanking1);
    }


    @XxlJob("test")
    public  void test() {
        List<Integer> fundUserIdList= appFundInfoMapper.getupdateFundUserId();
        BigDecimal bigDecimal = BigDecimal.ZERO;
        List<AdminFundConfig> configList = adminFundConfigMapper.selectList(new QueryWrapper<>());
        for (Integer userId:fundUserIdList) {
            List<AppFundInfo> infoList = appFundInfoMapper.getupdateFundByUserId(userId);
           // BigDecimal sumFund = BigDecimal.ZERO;
            //给上级带来奖励的总额
            BigDecimal  award = BigDecimal.ZERO;
            for (AppFundInfo appFundInfo:infoList) {
                BigDecimal rate = configList.stream().filter(s->s.getId().equals(appFundInfo.getFundId())).collect(Collectors.toList()).get(0).getRate();
                appFundInfo.setAmount(appFundInfo.getFund().multiply(rate));
               // sumFund = sumFund.add(appFundInfo.getAmount());
                if(appFundInfo.getState().equals(1)){
                    award = award.add(appFundInfo.getAmount());
                }
            }
            //  给所有等级奖励总额
            bigDecimal = bigDecimal.add(award);
            queueBonus(userId,award);
        }

    }


    public void fundRelease(Integer userId,BigDecimal amount){
        FundReleaseConsumer.FundReleaseDto dto = new FundReleaseConsumer.FundReleaseDto();
        dto.setAmount(amount.negate());
        dto.setUserId(userId);
        rabbitTemplate.convertAndSend( FundReleaseConsumer.queue,  JSONObject.toJSON(dto).toString());
    }

}
